package com.kylin.cf;

import java.io.IOException;
import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.eval.IRStatistics;
import org.apache.mahout.cf.taste.eval.RecommenderBuilder;
import org.apache.mahout.cf.taste.eval.RecommenderEvaluator;
import org.apache.mahout.cf.taste.eval.RecommenderIRStatsEvaluator;
import org.apache.mahout.cf.taste.impl.eval.AverageAbsoluteDifferenceRecommenderEvaluator;
import org.apache.mahout.cf.taste.impl.eval.GenericRecommenderIRStatsEvaluator;
import org.apache.mahout.cf.taste.impl.model.file.FileDataModel;
import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;
import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender;
import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.apache.mahout.cf.taste.similarity.UserSimilarity;
import org.apache.mahout.common.RandomUtils;

public class Judge extends Base {


  public static void main(String[] args) throws IOException, TasteException {
    init();
    runJudge();
  }

  public static void runJudge() throws TasteException, IOException {
    //强制每次生成相同的随机值，生成可重复的结果
    RandomUtils.useTestSeed();
    //数据装填
    DataModel model = new FileDataModel(tmpFile, ";");
    //推荐评估，使用平均值
    RecommenderEvaluator evaluator = new AverageAbsoluteDifferenceRecommenderEvaluator();
    //推荐评估，使用均方差
    //RecommenderEvaluator evaluator = new RMSRecommenderEvaluator();
    //用于生成推荐引擎的构建器，与上一例子实现相同

    RecommenderBuilder recommender = getRecommenderBuilder();

    //推荐程序评估值（平均差值）训练90%的数据，测试数据10%，《mahout in Action》使用的是0.7,但是出现结果为NaN
    double score = evaluator.evaluate(recommender,
        null,
        model,
        0.9,
        1.0);
    System.out.println(score);

    RandomUtils.useTestSeed();
    RecommenderIRStatsEvaluator irStatsEvaluator = new GenericRecommenderIRStatsEvaluator();
    IRStatistics stats = irStatsEvaluator.evaluate(
        recommender,
        null,
        model,
        null,
        RECOMMENDER_NUM,
        GenericRecommenderIRStatsEvaluator.CHOOSE_THRESHOLD,
        1.0);

    System.out.println(stats.getPrecision());
    System.out.println(stats.getRecall());
  }


  public static RecommenderBuilder getRecommenderBuilder() {
    return new RecommenderBuilder() {
      @Override
      public Recommender buildRecommender(DataModel model) throws TasteException {
        //用户相似度，多种方法 //TAG: 可以修改下列的Similarity
        UserSimilarity similarity = new PearsonCorrelationSimilarity(model);
        //用户邻居
        UserNeighborhood neighborhood = new NearestNUserNeighborhood(NEIGHBORHOOD_NUM, similarity,
            model);
        //一个推荐器
        return new GenericUserBasedRecommender(model, neighborhood, similarity);
      }
    };
  }
}
